package ivan.cheng.tuqu.util;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Rect;

 public class BitmapUtil {
	 public static final int MAXLENGTHFORNEWTREASUR = 140;
	 public static final int MAXLENGTHFORDETAILS = 150;
	 public static final int MAXLENGTHFORAVATAR = 40;
	 private static BitmapUtil sManager = null;
	 public static synchronized BitmapUtil instance() {
	        if (sManager == null) {
	            sManager = new BitmapUtil();
	        }
	        return sManager;
	    }
	 
	 /**
	  * 函数说明:回收不使用的BMP资源
	  * @param
	  * bmp 需要被系统回收的bitmap
	  * @see 整个应用程序用用到位图资源回收的务必使用此方法
	  * */
	 public void SafeRecycle(Bitmap bmp)
	 {
		 if(bmp != null && !bmp.isRecycled())
			 bmp.recycle();
	 }
	 
	 /**
	  * 函数说明:查看BitmapFactory.decodeFile(String pathName)
	  * */
	 public Bitmap DecodeFromFile(String pathname)
		{
			Bitmap bmp = null;
			try{
			bmp = BitmapFactory.decodeFile(pathname);
			}
			catch(OutOfMemoryError oe)
			{
				HandleOutOfMemory();
			}
			if(null == bmp)
			{
				FileUtil.getInstance().delFile(pathname);
			}
			return bmp;
		}
		
	 /**
	  * 函数说明:查看BitmapFactory.decodeFile(InputStream is)
	  * */
		public Bitmap DecodeFromStream(InputStream is)
		{
			Bitmap bmp = null;
			try{
			bmp = BitmapFactory.decodeStream(is);
			}
			catch(OutOfMemoryError oe)
			{
				HandleOutOfMemory();
			}
			return bmp;
		}
		
		 /**
		  * 函数说明:查看BitmapFactory.decodeFile(InputStream is)
		  * */
			public Bitmap DecodeFromStream(InputStream is,Rect outPadding, BitmapFactory.Options opts)
			{
				Bitmap bmp = null;
				try{
				bmp = BitmapFactory.decodeStream(is, outPadding, opts);
				}
				catch(OutOfMemoryError oe)
				{
					HandleOutOfMemory();
				}
				return bmp;
			}
		
		 /**
		  * 函数说明:查看BitmapFactory.decodeByteArray
		  * */
		public Bitmap DecodeFromByteArray(byte[] data, int offset, int length, Options opts)
		{
			Bitmap bmp = null;
			try{
			bmp = BitmapFactory.decodeByteArray(data,offset,length,opts);
			}
			catch(OutOfMemoryError oe)
			{
				HandleOutOfMemory();
			}
			return bmp;
		}
		
		/**
		  * 函数说明:查看Bitmap.createBitmap
		  * */
		public Bitmap createBitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter)
		{
			Bitmap bmp = null;
			try{
			bmp = Bitmap.createBitmap(source, x, y, width, height, m, filter);
			}
			catch(OutOfMemoryError oe)
			{
				HandleOutOfMemory();
			}
			return bmp;
		}

		/**
		  * 函数说明:查看Bitmap.createBitmap
		  * */
		public Bitmap createBitmap(int width, int height, Config config)
		{
			Bitmap bmp = null;
			try{
			bmp = Bitmap.createBitmap(width, height,config);
			}
			catch(OutOfMemoryError oe)
			{
				HandleOutOfMemory();
			}
			return bmp;
		}
		
		/**
		  * 函数说明:查看Bitmap.createBitmap
		  * */
		public Bitmap createBitmap(int[] colors, int offset, int stride, int width, int height, Config config)
		{
			Bitmap bmp = null;
			try{
			bmp = Bitmap.createBitmap(colors,offset,stride,width, height,config);
			}
			catch(OutOfMemoryError oe)
			{
				HandleOutOfMemory();
			}
			return bmp;
		}
		
		/**
		  * 函数说明:查看Bitmap.createBitmap
		  * */
		public Bitmap createBitmap(Bitmap source, int x, int y, int width, int height)
		{
			Bitmap bmp = null;
			try{
			bmp = Bitmap.createBitmap(source,x,y,width, height);
			}
			catch(OutOfMemoryError oe)
			{
				HandleOutOfMemory();
			}
			return bmp;
		}
	
	/**
	 * 函数说明:缩放图片，并把图片保存到指定目录下
	 * @return 返回缩放后的图片
	 * 
	 * @param
	 *  bitmapOrg 源图片
	 *  size 需要缩放的尺寸,为正方形
	 *  destPath 需要保存缩放后的尺寸
	 *  
	 *  @see 只做小图片缩放使用，若图片太大会引起内存不足,比如直接使用高像素相机拍摄的图片等
	 * */
		
	public Bitmap resizePicture(Bitmap bitmapOrg, int size, String destPath){
		int width = bitmapOrg.getWidth();
        int height = bitmapOrg.getHeight();
        
        // calculate the scale - in this case = 0.4f
        float scaleWidth = ((float) size) / width;
        float scaleHeight = ((float) size) / height;
        
        // createa matrix for the manipulation
        Matrix matrix = new Matrix();
        // resize the bit map
        matrix.postScale(scaleWidth, scaleHeight);
        // rotate the Bitmap
       // if (rotate != 0){
       // 	matrix.postRotate(rotate);
      //  }

        // recreate the new Bitmap
        Bitmap resizedBitmap = createBitmap(bitmapOrg, 0, 0, 
                          width, height, matrix, true);
		File destFile = new File(destPath);
		if (destFile.exists()) {
			destFile.delete();
		}
		OutputStream os = null;
		try {
			os = new FileOutputStream(destFile);
			resizedBitmap.compress(CompressFormat.PNG, 75, os);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} finally{
			try {
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return resizedBitmap;
	}
	
	/**
	 * 函数说明:缩放图片
	 * @return 返回缩放后的图片
	 * 
	 * @param
	 *  fName 源图片路径
	 *  newWidth 新图片宽度
	 *  newHeight 新图片高度
	 *  
	 *  @see 
	 * */
	public Bitmap resizeBitmap(String fName, int newWidth, int newHeight){
		FileInputStream input = null;

		try {
			input = new FileInputStream(fName);
		} catch (FileNotFoundException e2) {
			e2.printStackTrace();
			LogUtil.w("resizeBitmap:"+e2.toString());
			return null;
		}

		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		//options.inPreferredConfig = Config.RGB_565;
		BitmapFactory.decodeStream(input, null, options);

		try {
			if (input != null)
			    input.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		int mWidth = options.outWidth;
		int mHeight = options.outHeight;

		int sWidth = newWidth;
		int sHeight = newHeight;

		int s = 1;
		while ((mWidth / s > sWidth * 2) && (mHeight / s > sHeight * 2)) {
			s *= 2;
		}
		options = new BitmapFactory.Options();
		options.inSampleSize = s;
		options.inDither = true;
		//options.i
		//options.inPreferredConfig = Config.RGB_565;
		try {
			input = new FileInputStream(fName);
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		}
		Bitmap bitmap = BitmapFactory.decodeStream(input, null, options);
		try {
			if (input != null)
			    input.close();
		} catch (IOException e) {
			e.printStackTrace();
			LogUtil.w("resizeBitmap:"+e.toString());
		}

		// 原始图片的尺寸
		int bmpWidth = bitmap.getWidth();
		int bmpHeight = bitmap.getHeight();

		// 缩放图片的尺寸
		float scaleWidth = (float) sWidth / bmpWidth;
		float scaleHeight = (float) sHeight / bmpHeight;
		Matrix matrix = new Matrix();
		matrix.postScale(scaleWidth, scaleHeight);

		// 产生缩放后的Bitmap对象
		Bitmap resizeBitmap = createBitmap(bitmap, 0, 0, bmpWidth,
				bmpHeight, matrix, true);
		if (!bitmap.equals(resizeBitmap))
			bitmap.recycle();
		return resizeBitmap;
	}
	
	
	/**
	 * 函数说明:等比例缩放图片
	 * @return 返回缩放后的图片
	 * 
	 * @param
	 *  fName 源图片路径
	 *  newWidth 最小宽度
	 *  newHeight 最小高度
	 *  
	 *  @see 
	 * */
	public Bitmap ratioBitmap(String fName, int newWidth, int newHeight){
		FileInputStream input = null;

		try {
			input = new FileInputStream(fName);
		} catch (FileNotFoundException e2) {
			e2.printStackTrace();
			return null;
		}

		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		//options.inPreferredConfig = Config.RGB_565;
		BitmapFactory.decodeStream(input, null, options);

		try {
			if (input != null)
			    input.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		int mWidth = options.outWidth;
		int mHeight = options.outHeight;

		int sWidth = newWidth;
		int sHeight = newHeight;

		int s = 1;
		while ((mWidth / s > sWidth * 2) || (mHeight / s > sHeight * 2)) {
			s *= 2;
		}
		options = new BitmapFactory.Options();
		options.inSampleSize = s;
		//options.inDither = true;
		//options.inPreferredConfig = Config.RGB_565;
		try {
			input = new FileInputStream(fName);
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		}
		Bitmap tempBitmap = DecodeFromStream(input, null, options);
//		float fRodio = ((float)s*newWidth)/mWidth;
//		
//		Matrix m = new Matrix();
//		m.postScale(fRodio,fRodio);
//		Bitmap bitmap = BitmapUtil.instance().createBitmap(tempBitmap,
//				0,0,tempBitmap.getWidth(),tempBitmap.getHeight(),m,true);
//		if(!tempBitmap.equals(bitmap))
//			tempBitmap.recycle();
		try {
			if (input != null)
			    input.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return tempBitmap;
	}
	
	/**
	 * 函数说明:获取图片区域的某一块
	 * @return 返回缩放后的图片
	 * 
	 * @param
	 *  fName 源图片路径
	 *  newWidth 最小宽度
	 *  newHeight 最小高度
	 *  
	 *  @see 
	 * */
	public Bitmap trimBitmap(String fName, int ileftMargin,int itopMargin,int newWidth, int newHeight,int irightMargin,int iBottomMargin){
		FileInputStream input = null;

		try {
			input = new FileInputStream(fName);
		} catch (FileNotFoundException e2) {
			e2.printStackTrace();
		}

		//首先获取图片的高度和宽度
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		//options.inPreferredConfig = Config.RGB_565;
		BitmapFactory.decodeStream(input, null, options);

		try {
			if (input != null)
			    input.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		int mWidth = options.outWidth;
		int mHeight = options.outHeight;

		//然后获取我们要的区域的图片
		
		
		int sWidth = newWidth+ileftMargin+irightMargin;//
		int sHeight = newHeight+itopMargin+iBottomMargin;

		int s = 1;
		while ((mWidth / s > sWidth * 2) || (mHeight / s > sHeight * 2)) {
			s *= 2;
		}
		options = new BitmapFactory.Options();
		options.inSampleSize = s;
		//options.
		//options.inPreferredConfig = Config.RGB_565;
		try {
			input = new FileInputStream(fName);
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		}
		Bitmap bitmap = BitmapFactory.decodeStream(input, null, options);
		try {
			if (input != null)
			    input.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

		// 原始图片的尺寸
		int bmpWidth = bitmap.getWidth();
		int bmpHeight = bitmap.getHeight();
		
		float fL = (float)bmpWidth*ileftMargin/sWidth;
		float ft = (float)bmpHeight*itopMargin/sHeight;
		float fw = (float)bmpWidth*newWidth/sWidth;
		float fh = (float)bmpHeight*newHeight/sHeight;
		Bitmap resizeBitmap = createBitmap(bitmap, (int)fL, (int)ft, (int)fw,(int)fh);
		
		//还需要不需要再进行一次缩放呢?
		// 缩放图片的尺寸
		//float scaleWidth = (float) sWidth / bmpWidth;
		//float scaleHeight = (float) sHeight / bmpHeight;
		//Matrix matrix = new Matrix();
		//matrix.postScale(scaleWidth, scaleHeight);

		// 产生缩放后的Bitmap对象
		//Bitmap resizeBitmap = createBitmap(bitmap, 0, 0, bmpWidth,
		//		bmpHeight, matrix, false);
		if (1 != s)
			bitmap.recycle();
		return resizeBitmap;
	}
	
	public Bitmap tripBitmap(Bitmap bitmap, Rect rect, int iMarginRight, int iMarginBottom) {
		
		int photoWidth = rect.right - rect.left;
		int photoHeight = rect.bottom - rect.top;
		Bitmap newb = createBitmap(photoWidth, photoHeight, Config.ARGB_8888 );//创建一个新的和SRC长度宽度一样的位图   
		Canvas cv = new Canvas(newb); 
//		cv.drawBitmap(photoBG, new Rect(0, 0, photoBG.getWidth(), photoBG.getHeight()),
//				new Rect(0, 0, photoWidth, photoHeight), null);//在 0，0坐标开始画入src 
//		
//		Bitmap childBitmap = (Bitmap)mFrameView.getTag(R.id.image_path_id);
		Rect srcRect = new Rect();
		srcRect.left = (int)(float)bitmap.getWidth()*rect.left/(rect.right+iMarginRight);
		srcRect.top  = (int)(float)bitmap.getHeight()*rect.top/(rect.bottom+iMarginBottom);
		srcRect.right = (int)(float)bitmap.getWidth()*(rect.right - rect.left)/(rect.right+iMarginRight);
		srcRect.bottom = (int)(float)bitmap.getHeight()*(rect.bottom - rect.top)/(rect.bottom+iMarginBottom);
		srcRect.right += srcRect.left;
		srcRect.bottom += srcRect.top;
		cv.drawBitmap(bitmap, srcRect, new Rect(0,0,photoWidth,photoHeight), null );

		//save all clip   
		cv.save(Canvas.ALL_SAVE_FLAG);//保存   
		
		//store   
		cv.restore();//存储   
		return newb;  
	}
	
	private void HandleOutOfMemory() {
		
		LogUtil.e("HandleOutOfMemory");
		/*Intent i = new Intent(I_BROADCAST_EVENT.sOOM);
		mApp.sendBroadcast(i);*/
	}
	
	public byte [] Bitmap2Bytes( String msPhotoPath) {  
		Bitmap bm = DecodeFromFile(msPhotoPath);
	    ByteArrayOutputStream baos = new ByteArrayOutputStream ( ) ;    
	    bm. compress( Bitmap. CompressFormat. PNG, 100, baos) ;    
	    return baos. toByteArray ( ) ;    
	   }    
}